package com.example.demo;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.Advisor;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.ProxyConfig;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.cglib.core.DebuggingClassWriter;

/**
 * @author bigbird-0101
 * @date 2024-07-03 22:20
 */
public class SpringProxyTest {
    public static void main(String[] args) {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\ideaWorkSpace4\\study-project\\com\\sun\\proxy");
        MaiPiao proxy = (MaiPiao) getProxy(new TargetSource() {
            @Override
            public Class<?> getTargetClass() {
                return ZhouJieLun.class;
            }
            @Override
            public Object getTarget() {
                return new ZhouJieLun();
            }
        }, SpringProxyTest.class.getClassLoader());
        proxy.maiPiao();
    }

    public static class ZhouJieLun implements MaiPiao{
        @Override
        public void maiPiao() {
            System.out.println("卖周杰伦的票咯");
        }
    }

    public interface MaiPiao{
        void maiPiao();
    }

    private static Object getProxy(TargetSource targetSource, ClassLoader classLoader) {
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(new ProxyConfig());
        Advisor advisor = new Advisor() {
            @Override
            public Advice getAdvice() {
                return new LogAdvice();
            }
            @Override
            public boolean isPerInstance() {
                return false;
            }
        };
        Advisor[] advisors = new Advisor[]{advisor};
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        proxyFactory.setFrozen(false);
        return proxyFactory.getProxy(classLoader);
    }

    public static class LogAdvice implements MethodInterceptor {
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("我开始执行");
            Object proceed = invocation.proceed();
            System.out.println("我执行完了");
            return proceed;
        }
    }
}
